package interfaceusuario;

import entidadesparaguardardadosteste.CasoDeTeste;
import gui.FachadaManipulacaoClassesDeUmProjeto;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

import propertieslinguagem.SingletonSetaLinguagemEArmazenaResourceBundle;

public class TelaEscolhaClasseASerTestada implements ActionListener, TreeSelectionListener
{
	/**
	 * a TelaEscolhaClasseASerTestada eh a etapa 1 da criacao de um caso de testes. Por isso, ela
	 * contem um atributo casoDeTesteAssociado. Quando o usuario escolher a classe para testar, 
	 *  TelaEscolhaClasseASerTestada vai setar no caso de teste associado o nome da classe escolhida e encaminha 
	 *  os dados para a segunda etapa da criacao de um caso de testes: escolher um metodo para testar.
	 */
	private CasoDeTeste casoDeTesteAssociado;
	private LinkedList<String> nomesPacotesDeUmProjeto;
	
	private JFrame janelaEscolhaClasseASerTestada;
	private JButton botaoContinuar;//botao vai voltar a listar os pacotes do projeto na tela
	private LinkedList<CasoDeTeste> casosDeTesteSendoCriados;

	private String nomeClasseEscolhidaComPacote;
	
	private JTree arvoreComListagemDaClasseEPacotes;
	
	private boolean projetoTemPacotes; //diz se o projeto a ser testado tem pacotes ou somente aquele "default package"
	
	
	public TelaEscolhaClasseASerTestada(String diretorioDoProjeto, LinkedList<CasoDeTeste> casosDeTesteSendoCriados)
	{
		this.casoDeTesteAssociado = casosDeTesteSendoCriados.getLast();//por enquanto, soh ha um caso de teste sendo criado. na outra tela eh que esse numero pode aumentar
		this.casosDeTesteSendoCriados = casosDeTesteSendoCriados;
		FachadaManipulacaoClassesDeUmProjeto fachadaManipulaClasses = FachadaManipulacaoClassesDeUmProjeto.getInstance();
		nomesPacotesDeUmProjeto = fachadaManipulaClasses.pegarTodosOsPacotesDoProjeto(diretorioDoProjeto);
		
		this.projetoTemPacotes = true; //vamos mudar esse booleano mais tarde se necessario
		
		this.nomeClasseEscolhidaComPacote = "";
		
	}
	
	public void desenharTelaEscolhaClasseASerTestada()
	{
		SingletonSetaLinguagemEArmazenaResourceBundle conheceLinguagemDoSistema = 
				SingletonSetaLinguagemEArmazenaResourceBundle.getInstance();
		String titulojanelaEscolha = conheceLinguagemDoSistema.getString("janelaEscolhaClasseASerTestadaTelaEscolhaClasseASerTestada");
		
		
		
		this.janelaEscolhaClasseASerTestada = new JFrame();
		this.janelaEscolhaClasseASerTestada.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		this.janelaEscolhaClasseASerTestada.setSize(d);
		this.janelaEscolhaClasseASerTestada.setTitle(titulojanelaEscolha);
		ImageIcon iconeMascoteParaJFrame = CriadorImageIcon.criarImageIcon("imagens/meganeiconjframe2.jpg", "testableIcon");
		this.janelaEscolhaClasseASerTestada.setIconImage(iconeMascoteParaJFrame.getImage());
		
		JPanel painelExplicacaoEscolhaClasse = this.criarPainelExplicacaoInformeClasseParaTestar();
		JPanel painelListaDePacotesDoProjeto = this.criarPainelListarPacotesDeUmProjeto();
		
		//agora, vamos criar o botao que volta a listar os pacotes de um projeto(inicialmente, ele fica oculto)
		
		String tituloBotaoContinuar = conheceLinguagemDoSistema.getString("botaoContinuarTelaInsiraCaminhoDoProjeto");
		this.botaoContinuar = new JButton(tituloBotaoContinuar + " >>");
		this.botaoContinuar.addActionListener(this);
		
		CriaPainelDeFundoComBackground criadorPainelPadrao = CriaPainelDeFundoComBackground.getInstance();
		JPanel painelEscolhaClassePraTestar = criadorPainelPadrao.criarPainelDeFundoPadraoDoSistema();
		GridBagLayout layoutPainelescolhaClasseParaTestar = new GridBagLayout();
		painelEscolhaClassePraTestar.setLayout(layoutPainelescolhaClasseParaTestar);
		GridBagConstraints g = new GridBagConstraints();
		g.gridx = 0;
		g.gridy = 0;
		g.gridheight = 3;
		painelEscolhaClassePraTestar.add(painelExplicacaoEscolhaClasse, g);
		
		g.gridy = 3;
		g.gridheight = 5;
		painelEscolhaClassePraTestar.add(painelListaDePacotesDoProjeto, g);
		
		g.gridy = 8;
		g.gridheight = 1;
		g.insets = new Insets(20, 0, 0, 0);
		painelEscolhaClassePraTestar.add(botaoContinuar, g);
		
		
		
		System.out.println("primeiro pacote do projeto:" + this.nomesPacotesDeUmProjeto.get(0));
		if(this.nomesPacotesDeUmProjeto.get(0).compareTo("") == 0)
		{
			//se o nome do primeiro pacote do projeto eh "", significa que o projeto nao tem pacotes
			//vamos mostrar logo as classes carregadas, nunca os pacotes
			this.projetoTemPacotes = false;
			
		}
		
		
		this.janelaEscolhaClasseASerTestada.add(painelEscolhaClassePraTestar);

		janelaEscolhaClasseASerTestada.setVisible(true);
		
	}
	
	
	
	private JPanel criarPainelExplicacaoInformeClasseParaTestar()
	{
		SingletonSetaLinguagemEArmazenaResourceBundle conheceLinguagemDoSistema = 
				SingletonSetaLinguagemEArmazenaResourceBundle.getInstance();
		String tituloDescricaoTestboot = conheceLinguagemDoSistema.getString("descricaoTestbootTelaEscolhaClasseASerTestada");
		
		String descricaoTestboot = tituloDescricaoTestboot;
		JLabel labelDescricao = CriadorTextLabel.criarTextLabel(descricaoTestboot);
		CriaPainelDeFundoComBackground criaPainelPadrao = CriaPainelDeFundoComBackground.getInstance();
		JPanel painelExplicacao = criaPainelPadrao.criarPainelDeFundoPadraoDoSistema();
	
		painelExplicacao.add(labelDescricao);
		return painelExplicacao;
	}
	
	private JPanel criarPainelListarPacotesDeUmProjeto()
	{
		
        
        
        DefaultMutableTreeNode topoListagemClassesProjeto = new 
        		DefaultMutableTreeNode("main");
        criarNodesPacotesEClassesDoProjeto(topoListagemClassesProjeto);
        
        this.arvoreComListagemDaClasseEPacotes = new JTree(topoListagemClassesProjeto);
        
        this.arvoreComListagemDaClasseEPacotes.getSelectionModel().
        			setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        
        this.arvoreComListagemDaClasseEPacotes.addTreeSelectionListener(this);
        
        
		
	
		JPanel painelListaDePacotes = new JPanel();
		//vamos soh botar a lista em um scrollpane antes de adicionar ao painel definitivamente...
		JScrollPane painelRolagemParaListaDePacotes = new JScrollPane(arvoreComListagemDaClasseEPacotes);
		painelRolagemParaListaDePacotes.setPreferredSize(new Dimension(700, 400));
		painelListaDePacotes.add(painelRolagemParaListaDePacotes);
		return painelListaDePacotes;
		
	}
	
	public void criarNodesPacotesEClassesDoProjeto(DefaultMutableTreeNode topoListagemClassesProjeto)
	{
		for(int i = 0; i < this.nomesPacotesDeUmProjeto.size(); i++)
		{
			String nomeDeUmPacote = this.nomesPacotesDeUmProjeto.get(i);
			DefaultMutableTreeNode nodeUmPacoteDoProjeto = 
					new DefaultMutableTreeNode(nomeDeUmPacote);
			topoListagemClassesProjeto.add(nodeUmPacoteDoProjeto);
			
			FachadaManipulacaoClassesDeUmProjeto fachadaManipulaClasses = FachadaManipulacaoClassesDeUmProjeto.getInstance();
			LinkedList<String> nomesClassesDoPacoteSelecionado = fachadaManipulaClasses.pegarNomesDasClassesDentroDeUmPacote(nomeDeUmPacote);
			for(int j = 0; j < nomesClassesDoPacoteSelecionado.size(); j++)
			{
				String umaClasseDoPacote = nomesClassesDoPacoteSelecionado.get(j);
				DefaultMutableTreeNode nodeUmaClasseDoPacote = 
						new DefaultMutableTreeNode(nomeDeUmPacote + "." + umaClasseDoPacote);
				nodeUmPacoteDoProjeto.add(nodeUmaClasseDoPacote);
				
			}
		}
		
	}

	@Override
	public void actionPerformed(ActionEvent arg0) 
	{
		Object objetoDaAcao = arg0.getSource();
		if(objetoDaAcao == this.botaoContinuar)
		{
			if(this.nomeClasseEscolhidaComPacote.length() > 0 && this.nomeClasseEscolhidaComPacote.endsWith(".") == false)
			{
				Cursor cursorEspera = new Cursor(Cursor.WAIT_CURSOR);
				this.janelaEscolhaClasseASerTestada.setCursor(cursorEspera);
				this.casoDeTesteAssociado.setNomeClasseAssociadaAoCasoDeTeste(this.nomeClasseEscolhidaComPacote);
				//o usuario agora vai passar para a etapa 2: escolher o metodo da classe que deseja testar no caso de teste.
				TelaEscolhaMetodoASerTestado telaEscolhaMetodoParaTestar = new TelaEscolhaMetodoASerTestado(this.casosDeTesteSendoCriados); 
				Cursor cursorNormal = new Cursor(Cursor.DEFAULT_CURSOR);
				this.janelaEscolhaClasseASerTestada.setCursor(cursorNormal);
				janelaEscolhaClasseASerTestada.dispose();
			}
			
		}
		
		
	}

	@Override
	public void valueChanged(TreeSelectionEvent e) 
	{
		 DefaultMutableTreeNode nodeSelecionado = (DefaultMutableTreeNode)
                 arvoreComListagemDaClasseEPacotes.getLastSelectedPathComponent();
		 if(nodeSelecionado != null)
		 {
			 if(nodeSelecionado.isLeaf())
			 {
				 
				 this.nomeClasseEscolhidaComPacote = "" + nodeSelecionado.getUserObject(); 
			 }
		 }
		
	}
	
	

}
